#!/usr/bin/python3
# -*- coding: utf8 -*-
# Date   : 2021/08/12
# Author : Kwan
# Email  : allenxian@live.com
# Blog   : https://my.oschina.net/u/4173440

import subprocess
from project.define import dev_logger, CarParkConfig


class InterFace():
    def __init__(self, ifname) -> None:
        self.ifname = ifname
        self.mac = ''
        self.state = ''
        self.type = ''
        self.method = ''
        self.addresses = ''
        self.gateway = ''
        self.dns = ''
        self.ssid = ''
        self.password = ''
        self.__identify_interface()

    def conn_info(self):
        return {
            "ifname":self.ifname,"mac":self.mac,"state":self.state,"type":self.type,"method":self.method,"addresses":self.addresses,
            "gateway":self.gateway,"dns":self.dns,"ssid":self.ssid,"password":self.password}

    def column_name(self):
        """
        数据名称
        """
        return {
            "ifname":"接口名稱","mac":"MAC地址","state":"連接狀態","type":"接口類型","method":"網絡模式","addresses":"IP地址",
            "gateway":"網關地址","dns":"DNS地址","ssid":"WiFi信號","password":"WiFi密碼"}

    def refresh_interface(self):
        """
        刷新接口
        """
        self.__identify_interface()

    def __identify_interface(self):
        """
        检查接口
        """
        device_status = subprocess.getoutput(f"nmcli device status | grep {self.ifname} | awk " + "'{print $2,$3}'").split("\n")
        self.type, self.state = device_status[0].split(" ")
        # self.type, self.state = subprocess.getoutput(f"nmcli device status | grep {self.ifname} | awk " + "'{print $2,$3}'").split(" ")[:2]
        self.mac = subprocess.getoutput(f"ip link show {self.ifname} | grep link/ether | awk " + "'{print $2}'").upper()
        self.method = subprocess.getoutput(f"nmcli con show {self.ifname} | grep ipv4.method | awk -F : " + "'{print $2}'").replace(" ", "")
        if self.method == "auto":
            if self.state == "connected":
                # 动态获取
                ret = subprocess.getoutput(f"nmcli con show {self.ifname} | grep IP4").split("\n")
                if len(ret) > 0:
                    keys = []
                    values = []
                    for i in ret:
                        s = i.replace(" ", "").split(":")
                        keys.append(s[0].replace("IP4.", ""))
                        values.append(s[1])
                    ip4 = dict(zip(keys, values))
                    self.addresses = ip4.get('ADDRESS[1]')
                    self.gateway = ip4.get('GATEWAY')
                    dns1 = ip4.get('DNS[1]')
                    self.dns = dns1
                    dns2 = ip4.get('DNS[2]')
                    if dns2:
                        self.dns = f"{dns1},{dns2}"
        elif self.method == 'manual':
            # 静态IP
            ret = subprocess.getoutput(f"nmcli con show {self.ifname} | grep ipv4").split("\n")
            if len(ret) > 0:
                keys = []
                values = []
                for i in ret:
                    s = i.replace(" ", "").split(":")
                    keys.append(s[0].replace("ipv4.", ""))
                    values.append(s[1])
                ipv4 = dict(zip(keys, values))
                self.addresses = ipv4.get('addresses')
                self.gateway = ipv4.get('gateway')
                self.dns = ipv4.get('dns')
        if self.type == "wifi":
            wifi_con = CarParkConfig()
            wifi_con.read(f"/etc/NetworkManager/system-connections/{self.ifname}.nmconnection", encoding="utf8")
            wifi_con.sections()
            self.ssid = wifi_con['wifi']['ssid']
            self.password = wifi_con['wifi-security']['psk']

    def __default_connect(self):
        """
        默认连接
        """
        if self.type == "ethernet":
        # 有线网络
            return f"nmcli con add con-name {self.ifname} type ethernet ifname {self.ifname} "
        elif self.type == "wifi":
            # 无线网络
            return f"nmcli dev wifi con {self.ssid} password {self.password} name {self.ifname} "
        
    def __uplink(self, cmd=None):
        """
        启用连接
        """
        if not cmd:
            cmd = self.__default_connect()
        ret = subprocess.getoutput(f"nmcli con del {self.ifname}")
        if "successfully" in ret:
            # 新增配置
            ret = subprocess.getoutput(cmd)
            if "successfully" in ret:
                subprocess.getoutput(f"nmcli con up {self.ifname}")
                subprocess.getoutput("nmcli con reload")
                return ret

    def modify_interface(self, **kwargs):
        """
        修改网络接口
        """
        try:
            snapshot = self.__dict__.copy()
            if snapshot != kwargs:
                self.__dict__.update(**kwargs)
                con_cmd = self.__default_connect()
                if self.method == "manual":
                    # 静态IP
                    con_cmd = con_cmd + f"ipv4.method manual ipv4.address {self.addresses} ipv4.gateway {self.gateway} ipv4.dns {self.dns}"
                    dev_logger.debug(f"更新连接信息：{self.ifname} => 静态IP {self.addresses} 网关 {self.gateway} DNS {self.dns}")
                else:
                    con_cmd = con_cmd + "ipv4.method auto"
                    dev_logger.debug(f"更新连接信息：{self.ifname} => 自动获取IP")
                if self.__uplink(con_cmd):
                    dev_logger.debug(f"网络更新成功：{kwargs}")
            else:
                dev_logger.debug("网络设置没有更改")
        except Exception as e:
            dev_logger.error(f"网络更新失败：{kwargs}，原因：{e}")
            if self.__uplink():
                dev_logger.debug("网络恢复默认设置")


InterfacesName = subprocess.getoutput("ip link | grep BROADCAST | awk -F : '{print $2}'").replace(" ","").split("\n")
InterFaces = [InterFace(i) for i in InterfacesName]